Fork me on GitHub

基于开源URL数据字符串特征的恶意性检测,本科毕业设计

最近整理了一下本科的毕业设计(2018年6月完成的),代码发布于https://github.com/metang326/malicious-URL-detection

URL异常检测本质上是一个分类问题,将输入的URL经过处理后得到特征,输入到分类其中,分类器输出分类结果,恶意的还是良性的。
在训练集和验证集的基础上训练了多个分类模型,训练集用于训练、验证集用来调整参数。

特征提取

数据预处理

首先,鉴于只有小部分URL的前缀有“http”,“https”以及“www”字段,并且这些字符对于恶意性检测并没有帮助,所以在预处理阶段我们将这些前缀删去。

但是要注意将前缀部分与其他部分出现的“http”等字段进行区分,如:“zylights.com/img/?us.battle.net/login/en/?ref=http%3A%2F%2Fkhcdcofus.battle.net%2Fd3%2Fen%2Findex&app=com-d3”中的“http”就出现在参数部分。

此外,由于URL的参数字段可能存在恶意代码,所以我们还需要对URL的编码问题进行考虑,以免影响检测的效果,比如参数字段中的“%20”代表的是空格。

URL结构划分

考虑到黑名单特征和主机特征的获取非常耗时,并且还会存在一定的噪声和缺失值,而基于内容的特征又非常“重量级”,并且在下载网页内容的过程中会给系统带来安全威胁。

因此,我们选择了基于词汇的URL特征,在能够取得较好检测效果的同时又可以保证“轻量级”和高安全性。为此,我们需要对URL进行深入的了解,URL的结构样例。

1
2
3
4
5
6
7
8
9
10
11
例如:
http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name
1.协议部分:“http:”,在Internet中有多种网络协议例如:http:, https:, ftp: 等。后面的“//“为分隔符
2.域名部分:“www.aspxfans.com”是url的域名部分,在Url中也可以使用ip地址作为域名使用
3.端口部分:跟在域名后面的成为端口,域名和端口之间使用“:”进行分割,端口不是Url的必须部分可以省略
4.虚拟目录部分:从域名后面的第一个"/"开始到最后一个“/‘截止称之为虚拟目录部分,虚拟目录也不是Url的必须部分,本次实例的虚拟目录是”/news/“
5.文件名部分:从域名后的最后一个"/"开始到"?"为止成为文件名部分,如果没有"?"则从域名后的最后一个"/"开始到"#"为止是文件部分,如果没有"?"和”#“,那么从域名后的最后一个"/"开始到结束,都是文件名部分,本例的文件名部分是”index.asp“。文件名部分也不是URl的必须部分,如果省略该部分则使用默认的文件名
6.锚部分:从”#“开始到最后,都是锚部分,本例中的锚部分是”name“,锚部分也不是一个url的必须部分。
7.参数部分:从"?"开始到"#"为止之间的部分成为参数部分,又称搜索部分,查询部分本例中的”boardID=5&ID=24618&page=1“称为参数部分参数部分允许有多个参数,参数与参数之间用"&"作为分隔符。
[URL结构讲解内容参考链接:https://www.jianshu.com/p/b35a94bafb96]

提取内容列表

由于协议部分对恶意URL的检测没有明显帮助,所以我们不考虑提取这部分作为特征。

在提取特征时,一条URL可以被分成域名、路径、查询参数、锚点四大部分,每个部分又分别是由数字、字母以及特殊符号构成的,我们可以根据特殊字符(例如“/”,“.”,“?”,“=”等)将URL切分为不同的token。这样,我们就可以将一条URL看作是由一组token组成的向量,从而获取到更加具体的特征。

针对URL整体以及它的每个部分,我们一共提取了85个特征,分为基于URL整体的特征、基于域名的特征、基于路径的特征、基于查询参数的特征以及基于锚点的特征。

其中的“恶意词出现次数”特征所统计的恶意词是根据malwaredomains.com下载的恶意域数据集(和训练集、验证集、测试集没有交集)统计出现次数较多的词。
Python自带的包可以根据恶意词的统计结果生成的词云图片,其中字体较大的数据出现频率更高。可以看出,“beget”“service”, “account”, “eby”, “paypal”, “login”, “confirm”这类词出现的频率很高,因为恶意网站经常模仿良性网站或者用一些有吸引力的词语,试图诱导用户输入账号以及登陆信息。

流行网站名是根据Alexa排名前500名的网站数据集进行统计得到的,有些恶意网站会通过模仿知名网站来迷惑用户。根据流行网站中出现的词,我们生成了词云后发现,流行词与恶意词存在着部分交集,比如“apple”、“google”、“facebook”这些词,因为恶意网站有时会假冒流行网站,选取相近的域名来迷惑用户。

所提取的全部特征见下表:

基于整体URL的特征 基于hostname的特征 基于path的特征 基于search的特征 基于hash的特征
URL长度 token个数 token个数 token个数 token个数
字母比例 特殊字符个数 path长度 search长度
数字比例 字母比例 目录深度(/) 参数个数(&)
特殊符号的种类个数 数字比例 最长token 方差
特殊字符个数 出现点的次数(.) 特殊符号的种类个数
URL深度(/) 是否是IP地址 方差
出现点的次数(.) 熵
存在@符号 token方差
顶级域名TLD hostname长度
出现恶意词的次数 字母出现次数
出现流行网站名的次数
出现.php或者.exe的次数
在除了开头位置出现http,www的次数
字母出现次数

特征分析

为了分析我们所选取的特征是否可以对恶意URL进行有效地检验,我们比较了恶意URL和良性URL在不同特征下的平均值。

在随机划分情况下,不同的子集上相同特征的平均值几乎相同,仅有非常微小的区别。然而,当以标签作为划分依据之后,可以看出恶意URL集和良性URL集在相同特征下,平均值有明显的差异。

基于整体URL的特征 恶意URL平均值 良性URL平均值
URL长度 55.78 47
字母比例 0.79 0.79
数字比例 0.075 0.06
特殊符号的种类个数 0.94 1.03
特殊字符个数 2.07 2.58
URL深度(/) 2.78 2.32
出现点的次数(.) 2.219 1.66
存在@符号 0.022 0
出现恶意词的次数 2.617 1.44
出现流行网站名的次数 0.922 0.67
出现.php或者.exe的次数 0.279 0.04
在除了开头位置出现http,www的次数 0.039 0
基于hostname的特征 恶意URL平均值 良性URL平均值
token个数 2.48 2.35
特殊字符个数 0.15 0.06
字母比例 0.887 0.9
数字比例 0.022 0.006
出现点的次数(.) 1.346 1.29
熵 3.398 3.31
token方差 3.943 3.2
hostname长度 15.8 14.36
基于path的特征 恶意URL平均值 良性URL平均值
token个数 3.48 4.25
path长度 21.466 23.18
目录深度(/) 1.739 1.31
最长token 1.57 0.92
特殊符号的种类个数 0.795 0.97
方差 2.27 1.71
基于search的特征 恶意URL平均值 良性URL平均值
token个数 1.46 0.56
search长度 11.04 2.75
参数个数(&) 0.27 0.076
方差 1.05 0.37

模型训练

在提取特征的基础上,使用sklearn库中自带的分类模型在训练集上进行模型训练,根据各个分类器在验证集上的效果,在投票时设置了不同的权重。精确率高的分类器权重更高,也就是我们认为它的结果更加可信。

阈值在代码里的设置是,随机森林或者梯度提升树中只要有一个认为URL是恶意的,那就是恶意的,因为这两个模型的准确率比较高。剩下的四个分类器需要同时认为该URL是恶意的时候 才认为它是恶意的

实验结果

从kdnuggets上收集到了带标签(good/bad)的URL数据集,共416350条,其中异常数据(bad)71556条,占比17.19%;
正常数据(good)344794条,占比82.81%。

将全体数据划分为训练集(70%),验证集(15%)和测试集(15%),并且在每个集合中均保持异常数据所占比例相同。

分类器模型 准确度(%) 精确度(%) 召回率(%)
贝叶斯 85.88 60.82 50.25
AdaBoost 92.84 86.05 69.65
随机森林 97.13 95.9 87.05
决策树 94.63 83.9 85.11
逻辑回归 90.86 83.29 58.58
梯度提升树 96.35 93.7 84.45
基于投票的分类器 97.1 92.51 90.48
-------------本文结束感谢您的阅读-------------